package work02.atm;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.*;

/**
 * @author sunlggggg
 * @date 2017/4/16
 */
public class ATMServiceTest {


    ATMService atmService = null;
    MockDbConnection mockDbConnection = null;


    @Before
    public void setUp() throws Exception {
        // cardnNo password balance
        //Account a=new Account("1","11111",300);
        //Account b=new Account("2","22222",2000);
        mockDbConnection = new MockDbConnection();
        atmService = new ATMService(mockDbConnection);
    }

    @Test
    public void withDrawCase1() throws Exception {
        try {
            atmService.withDraw("12", 100);
            fail("Should have thrown an Exception because cardNo is not existed!");
        } catch (Exception e) {
            assertThat(e.getMessage(), containsString("cardNo is not existed!"));
        }
    }

    @Test
    public void withDrawCase2() throws Exception {
        atmService.withDraw("1", 100);
        Assert.assertEquals(mockDbConnection.getAccount("1").getBalance(), 200);
    }

    @Test
    public void withDrawCase3() throws Exception {
        try {
            atmService.withDraw("1", 100000);
            fail("Should have thrown an Exception because the balance is not negative!");
        } catch (Exception e) {
            assertThat(e.getMessage(), containsString("cardNo is not negative!"));
        }
    }

    @Test
    public void depositCase1() throws Exception {
        try {
            atmService.deposit("12", 100);
            fail("Should have thrown an Exception because cardNo is not existed!");
        } catch (Exception e) {
            assertThat(e.getMessage(), containsString("cardNo is not existed!"));
        }
    }

    @Test
    public void depositCase2() throws Exception {
        atmService.deposit("1", 100);
        Assert.assertEquals(mockDbConnection.getAccount("1").getBalance(), 400);
    }

    @Test
    public void depositCase3() throws Exception {
        try {
            atmService.deposit("1", Integer.MAX_VALUE);
            fail("Should have thrown an Exception because balance is overflow!");
        } catch (Exception e) {
            assertThat(e.getMessage(), containsString("balance is overflow!"));
        }
    }

    @Test
    public void transferCase1() throws Exception {
        try {
            atmService.transfer("12", "1", 1212);
            fail("Should have thrown an Exception because cardNo1 is not existed!");
        } catch (Exception e) {
            assertThat(e.getMessage(), containsString("cardNo1 is not existed!"));
        }
    }

    @Test
    public void transferCase2() throws Exception {
        try {
            atmService.transfer("1", "12", 400);
            fail("Should have thrown an Exception because cardNo2 is not existed!");
        } catch (Exception e) {
            assertThat(e.getMessage(), containsString("cardNo2 is not existed!"));
        }
    }

    @Test
    public void transferCase3() throws Exception {
        try {
            atmService.transfer("1", "2", 400);
            fail("Should have thrown an Exception because balance is not negative!");
        } catch (Exception e) {
            assertThat(e.getMessage(), containsString("balance is not negative!"));
        }
    }

    @Test
    public void transferCase4() throws Exception {
        try {
            atmService.transfer("1", "2", 5000);
            fail("Should have thrown an Exception because balance is overflow!");
        } catch (Exception e) {
            assertThat(e.getMessage(), containsString("balance is overflow!"));
        }
    }

    @Test
    public void transferCase5() throws Exception {
        int balance1 = mockDbConnection.getAccount("1").getBalance();
        int balance2 = mockDbConnection.getAccount("2").getBalance();
        atmService.transfer("1", "2", 100);
        Assert.assertTrue(mockDbConnection.getAccount("1").getBalance() == balance1 - 100);
        Assert.assertTrue(mockDbConnection.getAccount("2").getBalance() == balance2 + 100);
    }

    @Test
    public void inquiryCase1() throws Exception {
        try {
            atmService.inquiry("12");
            fail("Should have thrown an Exception because cardNo1 is not existed!");
        } catch (Exception e) {
            assertThat(e.getMessage(), containsString("cardNo1 is not existed!"));
        }

    }

    @Test
    public void inquiryCase2() throws Exception {
        Assert.assertEquals(atmService.inquiry("1"),300);
    }
}